home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / BenchMarks / ByteBenchmark / src / dummy.c < prev    next >
C/C++ Source or Header  |  1994-01-27  |  7KB  |  318 lines

  1. /*******************************************************************************
  2.  *  The BYTE UNIX Benchmarks - Release 3
  3.  *          Module: dummy.c   SID: 3.3 5/15/91 19:30:19
  4.  *          
  5.  *******************************************************************************
  6.  * Bug reports, patches, comments, suggestions should be sent to:
  7.  *
  8.  *    Ben Smith, Rick Grehan or Tom Yager
  9.  *    ben@bytepb.byte.com   rick_g@bytepb.byte.com   tyager@bytepb.byte.com
  10.  *
  11.  *******************************************************************************
  12.  *  Modification Log:
  13.  *
  14.  ******************************************************************************/
  15. /*
  16.  *  Hacked up C program for use in the standard shell.? scripts of
  17.  *  the multiuser test.  This is based upon makework.c, and is typically
  18.  *  edited using edscript.2 before compilation.
  19.  *
  20.  * $Header: dummy.c,v 3.4 87/06/23 15:54:53 kjmcdonell Beta $
  21.  */
  22. char SCCSid[] = "@(#) @(#)dummy.c:3.3 -- 5/15/91 19:30:19";
  23.  
  24. #include <stdio.h>
  25. #include <signal.h>
  26.  
  27. #define DEF_RATE    5.0
  28. #define GRANULE        5
  29. #define CHUNK        60
  30. #define MAXCHILD    12
  31. #define MAXWORK        10
  32.  
  33. float    thres;
  34. float    est_rate = DEF_RATE;
  35. int    nusers;        /* number of concurrent users to be simulated by
  36.              * this process */
  37. int    firstuser;    /* ordinal identification of first user for this
  38.              * process */
  39. int    nwork = 0;    /* number of job streams */
  40. int    exit_status = 0;    /* returned to parent */
  41. int    sigpipe;    /* pipe write error flag */
  42.  
  43. struct st_work {
  44.     char    *cmd;        /* name of command to run */
  45.     char    **av;        /* arguments to command */
  46.     char    *input;        /* standard input buffer */
  47.     int    inpsize;    /* size of standard input buffer */
  48. } work[MAXWORK];
  49.  
  50. struct {
  51.     int    xmit;    /* # characters sent */
  52.     char    *bp;    /* std input buffer pointer */
  53.     int    blen;    /* std input buffer length */
  54.     int    fd;    /* stdin to command */
  55.     int    pid;    /* child PID */
  56.     char    *line;    /* start of input line */ 
  57.     int    firstjob;    /* inital piece of work */
  58.     int    thisjob;    /* current piece of work */
  59. } child[MAXCHILD], *cp;
  60.  
  61. main(argc, argv)
  62. int    argc;
  63. char    *argv[];
  64. {
  65.     int        i;
  66.     int        l;
  67.     int        fcopy = 0;    /* fd for copy output */
  68.     int        master = 1;    /* the REAL master, == 0 for clones */
  69.     int        nchild;        /* no. of children for a clone to run */
  70.     int        done;        /* count of children finished */
  71.     int        output;        /* aggregate output char count for all
  72.                    children */
  73.     int        c;
  74.     int        thiswork = 0;    /* next job stream to allocate */
  75.     int        nch;        /* # characters to write */
  76.     int        written;    /* # characters actully written */
  77.     char    logname[15];    /* name of the log file(s) */
  78.     int        onalarm();
  79.     int        pipeerr();
  80.     int        wrapup();
  81.     int        grunt();
  82.     char    *malloc();
  83.     int        pvec[2];    /* for pipes */
  84.     char    *p;
  85.     char    *prog;        /* my name */
  86.  
  87. #if ! debug
  88.     freopen("masterlog.00", "a", stderr);
  89. #endif
  90.     fprintf(stderr, "*** New Run ***  ");
  91.     prog = argv[0];
  92.     while (argc > 1 && argv[1][0] == '-')  {
  93.     p = &argv[1][1];
  94.     argc--;
  95.     argv++;
  96.     while (*p) {
  97.         switch (*p) {
  98.         case 'r':
  99.             /* code DELETED here */
  100.             argc--;
  101.             argv++;
  102.             break;
  103.  
  104.         case 'c':
  105.             /* code DELETED here */
  106.             lseek(fcopy, 0L, 2);    /* append at end of file */
  107.             break;
  108.  
  109.         default:
  110.         fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
  111.             exit(4);
  112.         }
  113.         p++;
  114.     }
  115.     }
  116.     
  117.     if (argc < 2) {
  118.     fprintf(stderr, "%s: missing nusers\n", prog);
  119.     exit(4);
  120.     }
  121.  
  122.     nusers = atoi(argv[1]);
  123.     if (nusers < 1) {
  124.     fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
  125.     exit(4);
  126.     }
  127.     fprintf(stderr, "%d Users\n", nusers);
  128.     argc--;
  129.     argv++;
  130.  
  131.     /* build job streams */
  132.     getwork();
  133. #if debug
  134.     dumpwork();
  135. #endif
  136.  
  137.     /* clone copies of myself to run up to MAXCHILD jobs each */
  138.     firstuser = MAXCHILD;
  139.     fprintf(stderr, "master pid %d\n", getpid());
  140.     fflush(stderr);
  141.     while (nusers > MAXCHILD) {
  142.     fflush(stderr);
  143.     if (nusers >= 2*MAXCHILD)
  144.         /* the next clone must run MAXCHILD jobs */
  145.         nchild = MAXCHILD;
  146.     else
  147.         /* the next clone must run the leftover jobs */
  148.         nchild = nusers - MAXCHILD;
  149.     if ((l = fork()) == -1) {
  150.         /* fork failed */
  151.         fatal("** clone fork failed **\n");
  152.         goto bepatient;
  153.     } else if (l > 0) {
  154.         fprintf(stderr, "master clone pid %d\n", l);
  155.         /* I am the master with nchild fewer jobs to run */
  156.         nusers -= nchild;
  157.         firstuser += MAXCHILD;
  158.         continue;
  159.     } else {
  160.         /* I am a clone, run MAXCHILD jobs */
  161. #if ! debug
  162.         sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
  163.         freopen(logname, "w", stderr);
  164. #endif
  165.         master = 0;
  166.         nusers = nchild;
  167.         break;
  168.     }
  169.     }
  170.     if (master)
  171.     firstuser = 0;
  172.  
  173.     close(0);
  174.  
  175.     /* code DELETED here */
  176.  
  177.     fflush(stderr);
  178.  
  179.     srand(time(0));
  180.     thres = 0;
  181.     done = output = 0;
  182.     for (i = 0; i < nusers; i++) {
  183.     if (child[i].blen == 0)
  184.         done++;
  185.     else
  186.         thres += est_rate * GRANULE;
  187.     }
  188.     est_rate = thres;
  189.  
  190.     signal(SIGALRM, onalarm);
  191.     signal(SIGPIPE, pipeerr);
  192.     alarm(GRANULE);
  193.     while (done < nusers) {
  194.     for (i = 0; i < nusers; i++) {
  195.         cp = &child[i];
  196.         if (cp->xmit >= cp->blen) continue;
  197.         l = rand() % CHUNK + 1;    /* 1-CHUNK chars */
  198.         if (l == 0) continue;
  199.         if (cp->xmit + l > cp->blen)
  200.         l = cp->blen - cp->xmit;
  201.         p = cp->bp;
  202.         cp->bp += l;
  203.         cp->xmit += l;
  204. #if debug
  205.         fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
  206. #endif
  207.         while (p < cp->bp) {
  208.         if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
  209.             /* write it out */
  210.             nch = p - cp->line + 1;
  211.             if ((written = write(cp->fd, cp->line, nch)) != nch) {
  212.  
  213.             /* code DELETED here */
  214.  
  215.             }
  216.             if (fcopy)
  217.             write(fcopy, cp->line, p - cp->line + 1);
  218. #if debug
  219.             fprintf(stderr, "child %d gets \"", i);
  220.             {
  221.             char *q = cp->line;
  222.             while (q <= p) {
  223.                 if (*q >= ' ' && *q <= '~')
  224.                     fputc(*q, stderr);
  225.                 else
  226.                     fprintf(stderr, "\\%03o", *q);
  227.                 q++;
  228.             }
  229.             }
  230.             fputc('"', stderr);
  231. #endif
  232.             cp->line = &p[1];
  233.         }
  234.         p++;
  235.         }
  236.         if (cp->xmit >= cp->blen) {
  237.         done++;
  238.         close(cp->fd);
  239. #if debug
  240.     fprintf(stderr, "child %d, close std input\n", i);
  241. #endif
  242.         }
  243.         output += l;
  244.     }
  245.     while (output > thres) {
  246.         pause();
  247. #if debug
  248.         fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
  249. #endif
  250.     }
  251.     }
  252.  
  253. bepatient:
  254.     alarm(0);
  255. /****
  256.  *  If everything is going OK, we should simply be able to keep
  257.  *  looping unitil 'wait' fails, however some descendent process may
  258.  *  be in a state from which it can never exit, and so a timeout
  259.  *  is used.
  260.  *  5 minutes should be ample, since the time to run all jobs is of
  261.  *  the order of 5-10 minutes, however some machines are painfully slow,
  262.  *  so the timeout has been set at 20 minutes (1200 seconds).
  263.  ****/
  264.  
  265.     /* code DELETED here */
  266.  
  267. }
  268.  
  269. onalarm()
  270. {
  271.     thres += est_rate;
  272.     signal(SIGALRM, onalarm);
  273.     alarm(GRANULE);
  274. }
  275.  
  276. grunt()
  277. {
  278.     /* timeout after label "bepatient" in main */
  279.     exit_status = 4;
  280.     wrapup();
  281. }
  282.  
  283. pipeerr()
  284. {
  285.     sigpipe++;
  286. }
  287.  
  288. wrapup()
  289. {
  290.     /* DUMMY, real code dropped */
  291. }
  292.  
  293. getwork()
  294. {
  295.  
  296.     /* DUMMY, real code dropped */
  297.     gets();
  298.     strncpy();
  299.     malloc(); realloc();
  300.     open(); close();
  301. }
  302.  
  303. fatal(s)
  304. char *s;
  305. {
  306.     int    i;
  307.     fprintf(stderr, s);
  308.     fflush(stderr);
  309.     perror("Reason?");
  310.     for (i = 0; i < nusers; i++) {
  311.     if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1)
  312.         fprintf(stderr, "pid %d killed off\n", child[i].pid);
  313.     }
  314.     fflush(stderr);
  315.     exit_status = 4;
  316.     return;
  317. }
  318.